home *** CD-ROM | disk | FTP | other *** search
/ Aminet 21 / Aminet 21 (1997)(GTI - Schatztruhe)[!][Oct 1997].iso / Aminet / comm / bbs / cit_src_7H21.lha / msgout.c < prev    next >
C/C++ Source or Header  |  1997-08-18  |  21KB  |  905 lines

  1. /*
  2. *                               msgout.c
  3. *
  4. * External Message writer.  For use with external OtherNet parsers.
  5. */
  6. /*
  7. *                               history
  8. *
  9. * 92Jan17 HAW  1.4 - Hard-wire room name to msgs; handle domain field.
  10. * 91Mar26 HAW  1.3 - Virtual rooms.
  11. * 89Sep25 HAW  1.2 - update for Route Mail.
  12. * 88Nov17 HAW  Created.
  13. */
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include "ctdl.h"
  17. #include "2ndfmt.h"
  18. #include "stdarg.h"
  19. #include "dos.h"
  20. #include "math.h"
  21. /*
  22. *                               contents
  23. *
  24. */
  25. #define TITLE           "C86Net Message Exporter "
  26. #define NO_ERROR        0
  27. #define BAD_ARGS        1
  28. #define BAD_TABLE       2
  29. #define NO_NODE         3
  30. #define FATAL           4
  31. #define BAD_OUT_FILE    5
  32. #define LF_ERROR        6
  33.  
  34. char onConsole=1, remoteSysop;
  35.  
  36. FILE            *outfile;
  37. extern FILE *upfd;
  38. extern CONFIG      cfg;                 /* Configuration variables      */
  39. extern MessageBuffer msgBuf;    /* The -sole- message buffer    */
  40. extern aRoom       roomBuf;             /* Room buffer */
  41. extern logBuffer   logBuf;
  42. extern FILE        *roomfl, *logfl;
  43. extern int         thisRoom;    /* Current room    */
  44. extern rTable      *roomTab;
  45. extern struct mBuf mFile1, mFile2;
  46. extern SListBase Serves;
  47. extern NetTable    *netTab;
  48. extern NetBuffer   netBuf, netTemp;
  49. extern FILE        *netfl;
  50. extern LogTable    *logTab;
  51. extern FILE        *msgfl, *msgfl2;
  52. FILE       *GlobalFd, *netMisc;
  53. static int RCount, SCount;
  54. extern int         thisNet;        /* Current node in use          */
  55. char *R_SH_MARK =  "&&";
  56. char *NON_LOC_NET= "%%";
  57. char *LOC_NET =    "++";
  58. char inNet = ANYTIME_NET;
  59.  
  60. void NetField(char field, char *value);
  61. void MsgOutGenInit(void);
  62. void MODoVirtuals(void);
  63. void Process(void);
  64. int  FindNet(label nm);
  65. int ThrowAll(int which, char *distance, MSG_NUMBER start, MSG_NUMBER end,
  66. char *room);
  67. void UtilRoomSend(int rover, char *send1, char *send2, char *send3);
  68. void HandleMessage(char *addr1, char *addr2, char *addr3);
  69. int  RoutePath(char *rp, char *str);
  70. char FindMessage(SECTOR_ID loc, MSG_NUMBER id);
  71. void NetFormat(void);
  72. void NowRouteMail(void);
  73. void MoutCC(char *);
  74. void MoutForeign(char *);
  75. int ReadRoutedDest(int c);
  76. int ReadRouted(void);
  77. void Intel32ToMotorola(UNS_32 *);
  78.  
  79. int  mPrintf(char *format, ...) {return 0; }  /* stub to quiet the linker */
  80.  
  81. /**
  82.   some statistics
  83. **/
  84. int total_msgs = 0;  /* total messages output */
  85.  
  86. /*
  87. * crashout()
  88. *
  89. * Crash exit handler.
  90. */
  91. void crashout(str)
  92. char *str;
  93.   {
  94.   printf(str);
  95.   writeSysTab();
  96.   exit(FATAL);
  97.  
  98.   }
  99. /*
  100. * main()
  101. *
  102. * Main manager
  103. */
  104. int  main(int, char **);
  105. int  main(argc, argv)
  106. char **argv;
  107. int  argc;
  108.   {
  109.   int rover;
  110.   extern char *WRITE_ANY;
  111.   printf("%s %s\n%s\n\n", TITLE, VERSION_NAME, COPYRIGHT);
  112.   /* not enough arguments?  Explain. */
  113.   if (argc < 3)
  114.     {
  115.     printf("usage: MSGOUT nodename file\n");
  116.     exit(BAD_ARGS);
  117.  
  118.     }
  119.   cfg.weAre = UTILITY;
  120.   if (!readSysTab(TRUE, TRUE))
  121.     {
  122.     exit(BAD_TABLE);
  123.  
  124.     }
  125.   if (access(LOCKFILE, 0) != ERROR)
  126.     {
  127.     printf("Please do not run MsgOut using Outside Commands.\n");
  128.     exit(LF_ERROR);
  129.  
  130.     }
  131.   MsgOutGenInit();
  132.   VirtInit();
  133.   if (FindNet(argv[1]) == ERROR)
  134.     {
  135.     writeSysTab();
  136.     printf("Could not find node %s.\n", argv[1]);
  137.     exit(NO_NODE);
  138.  
  139.     }
  140.   if ((outfile = fopen(argv[2], WRITE_ANY)) == NULL)
  141.     {
  142.     writeSysTab();
  143.     printf("Couldn't open output file %s.\n", argv[2]);
  144.     exit(BAD_OUT_FILE);
  145.  
  146.     }
  147.   Process();
  148.   putNet(thisNet, &netBuf);
  149.   writeSysTab();
  150.   printf(" %d total messages output\n", total_msgs);
  151.   return 0;
  152.   }
  153. /*
  154. * MsgOutGenInit()
  155. *
  156. * This handles general initialization.
  157. */
  158. void MsgOutGenInit()
  159.   {
  160.   SYS_FILE fn;
  161.   initNetBuf(&netBuf);
  162.   initNetBuf(&netTemp);
  163.   makeSysName(fn, "ctdlnet.sys", &cfg.netArea);
  164.   openFile(fn, &netfl);
  165.   initRoomBuf(&roomBuf);
  166.   makeSysName(fn, "ctdlroom.sys", &cfg.roomArea);
  167.   openFile(fn, &roomfl);
  168.   InitMsgBase();
  169.  
  170.   }
  171. /*
  172. * Process()
  173. *
  174. * This is the main processor.
  175. */
  176. void Process()
  177.   {
  178.   char          *send1, *send2, *send3;
  179.   label         temp;
  180.   SYS_FILE              fn;
  181.   FILE          *mail;
  182.   int                   rover;
  183.   extern char           *READ_ANY;
  184.   struct netMLstruct    buf;
  185.   /* first we handle Mail>. */
  186.   if (netBuf.nbflags.normal_mail)
  187.     {
  188.     sPrintf(temp, "%d.ml", thisNet);
  189.     makeSysName(fn, temp, &cfg.netArea);
  190.     if ((mail = fopen(fn, READ_ANY)) == NULL)
  191.       {
  192.       printf("WARNING: Couldn't open %s for mail delivery to %s.\n",
  193.       fn, netBuf.netName);
  194.  
  195.       }
  196.     else
  197.       {
  198.       while (getMLNet(mail, buf))
  199.       if (FindMessage(buf.ML_loc, buf.ML_id))
  200.         {
  201.         strCpy(msgBuf.mbroom, "Mail");
  202.         NetFormat();
  203.  
  204.         }
  205.       fclose(mail);
  206.       unlink(fn);               /* kill mail file */
  207.  
  208.       }
  209.     netBuf.nbflags.normal_mail = FALSE;
  210.  
  211.     }
  212.   NowRouteMail();               /* now handle any route mail */
  213.   /* now we handle the shared rooms */
  214.   for (rover = 0; rover < SHARED_ROOMS; rover++)
  215.     {
  216.     /* if we share this room, check for new msgs. */
  217.     if (isSharedRoom(thisNet, rover) && roomValidate(thisNet, rover))
  218.       {
  219.       getRoom(netRoomSlot(rover));
  220.       send1 = R_SH_MARK;
  221.       send2 = send3 = "guh";
  222.       switch (roomBuf.rbShareType)
  223.         {
  224.         case REG_HOST:
  225.         printf("WARNING: Please do not use Regional Host settings.\n");
  226.         printf("\nThey are obsolete.\n");
  227.         case PEON:
  228.         break;
  229.         case BACKBONE:
  230.         switch (netBuf.netRooms[rover].mode)
  231.           {
  232.           case PEON:
  233.           send2  = NON_LOC_NET;
  234.           break;
  235.           case ACTIVE_BACKBONE:
  236.           case PASS_BACKBONE:
  237.           case REG_HOST:
  238.           send2 = NON_LOC_NET;
  239.           send3 = LOC_NET;
  240.           break;
  241.           default: crashout("shared rooms: #2");
  242.  
  243.           }
  244.         break;
  245.         default: crashout("shared rooms: #1");
  246.  
  247.         }
  248.       UtilRoomSend(rover, send1, send2, send3);
  249.  
  250.       }
  251.  
  252.     }
  253.   MODoVirtuals();
  254.   UpdVirtStuff();
  255.  
  256.   }
  257. /*
  258. * UtilRoomSend()
  259. *
  260. * Send stuff out.
  261. */
  262. void UtilRoomSend(rover, send1, send2, send3)
  263. int rover;
  264. char *send1, *send2, *send3;
  265.   {
  266.   int i;
  267.   for (i = 0; i < MSGSPERRM; i++)
  268.     {
  269.     if (roomBuf.msg[i].rbmsgNo > netBuf.netRooms[rover].lastMess)
  270.       {
  271.       if (FindMessage(roomBuf.msg[i].rbmsgLoc, roomBuf.msg[i].rbmsgNo))
  272.         {
  273.         strcpy(msgBuf.mbroom, roomBuf.rbname);
  274.         HandleMessage(send1, send2, send3);
  275.  
  276.         }
  277.  
  278.       }
  279.  
  280.     }
  281.   netBuf.netRooms[rover].lastMess = roomTab[thisRoom].rtlastMessage;
  282.   netTab[thisNet].netTRooms[rover].lastMess =
  283.   roomTab[thisRoom].rtlastMessage;
  284.  
  285.   }
  286. /*
  287. * HandleMessage()
  288. *
  289. * This decides if a message should be sent out.
  290. */
  291. void HandleMessage(addr1, addr2, addr3)
  292. char *addr1, *addr2, *addr3;
  293.   {
  294.   if ((strncmp(msgBuf.mbaddr, addr1, strLen(addr1)) == SAMESTRING  ||
  295.   strncmp(msgBuf.mbaddr, addr2, strLen(addr2))      == SAMESTRING  ||
  296.   strncmp(msgBuf.mbaddr, addr3, strLen(addr3))      == SAMESTRING) &&
  297.   RoutePath(LOC_NET, msgBuf.mbaddr)     != thisNet &&
  298.   RoutePath(NON_LOC_NET, msgBuf.mbaddr) != thisNet)
  299.     {
  300.     NetFormat();
  301.  
  302.     }
  303.  
  304.   }
  305. /*
  306. * RoutePath()
  307. *
  308. * This function returns the number of the node that routed this msg
  309. * to here.  If the msg was not routed in from a BackBone, then
  310. * return ERROR, which will never match another node's #.
  311. * 88Oct13: Now simply check for msg origin, assume if one exists
  312. * that it should be checked.  Don't remember why it is restricted
  313. * to only BACKBONE-routed msgs.  Doesn't seem necessary.
  314. */
  315. int RoutePath(rp, str)
  316. char *str, *rp;
  317.   {
  318.   if (strncmp(rp, str, strLen(rp)) == SAMESTRING)
  319.     {
  320.     if (strLen(str) != strLen(rp)) /* prevent return of 0 */
  321.     return atoi(str + 2);
  322.  
  323.     }
  324.   return ERROR;
  325.  
  326.   }
  327. /*
  328. * FindNet()
  329. *
  330. * This function will find the named node.  Stolen from searchNameNet/NETMISC.
  331. */
  332. int  FindNet(nm)
  333. label nm;
  334.   {
  335.   int rover;
  336.   for (rover = 0; rover < cfg.netSize; rover++)
  337.     {
  338.     if (netTab[rover].ntflags.in_use &&
  339.     hash(nm) == netTab[rover].ntnmhash)
  340.       {
  341.       getNet(rover, &netBuf);
  342.       if (strCmpU(netBuf.netName, nm) == SAMESTRING)
  343.       return rover;
  344.  
  345.       }
  346.  
  347.     }
  348.   return ERROR;
  349.  
  350.   }
  351. /*********** These functions stolen & modified from MSG.C ***************/
  352. /*
  353. * FindMessage()
  354. *
  355. * This gets all set up to do something with a message.  We use this rather
  356. * than the findMessage in libmsg.c so we can automatically read in the 'M'
  357. * field.
  358. */
  359. char FindMessage(loc, id)
  360. SECTOR_ID  loc;         /* sector in message.buf */
  361. MSG_NUMBER id;          /* unique-for-some-time ID# */
  362.   {
  363.   MSG_NUMBER here;
  364.   startAt(msgfl, &mFile1, loc, 0);
  365.   do
  366.     {
  367.     getMessage(getMsgChar, FALSE, TRUE, TRUE);
  368.     here = atol(msgBuf.mbId);
  369.  
  370.     }
  371.   while (here != id &&  mFile1.thisSector == loc);
  372.   return (char) ((here == id));
  373.  
  374.   }
  375. /*
  376. * NetFormat()
  377. *
  378. * This function writes a message to disk.
  379. */
  380. void NetFormat()
  381.   {
  382.   MSG_NUMBER val;
  383.   if (!msgBuf.mborig[0])
  384.   strCpy(msgBuf.mborig, cfg.nodeId + cfg.codeBuf);
  385.   if (!msgBuf.mboname[0])
  386.   strCpy(msgBuf.mboname, cfg.nodeName + cfg.codeBuf);
  387.   if (!msgBuf.mbsrcId[0])
  388.     {
  389.     val = atol(msgBuf.mbId);
  390.     sPrintf(msgBuf.mbsrcId, "%ld %ld",
  391.     (val & 0xffff0000) >> 16, val & 0xffffl);
  392.  
  393.     }
  394.   if (msgBuf.mbauth[0])   NetField('A', msgBuf.mbauth);
  395.   if (msgBuf.mbdate[0])   NetField('D', msgBuf.mbdate);
  396.   if (msgBuf.mbtime[0])   NetField('C', msgBuf.mbtime);
  397.   if (msgBuf.mboname[0])  NetField('N', msgBuf.mboname);
  398.   if (msgBuf.mbdomain[0]) NetField('X', msgBuf.mbdomain);
  399.   if (msgBuf.mborig[0])   NetField('O', msgBuf.mborig);
  400.   if (msgBuf.mbroom[0])   NetField('R', msgBuf.mbroom);
  401.   if (msgBuf.mbsrcId[0])  NetField('S', msgBuf.mbsrcId);
  402.   if (msgBuf.mbto[0])     NetField('T', msgBuf.mbto);
  403.   if (msgBuf.mbOther[0])  NetField('P', msgBuf.mbOther);
  404.   RunList(&msgBuf.mbCC, MoutCC);
  405.   RunList(&msgBuf.mbForeign, MoutForeign);
  406.   NetField('M', msgBuf.mbtext);
  407.   total_msgs++;
  408.   }
  409. /*
  410. * NetField()
  411. *
  412. * Work function to write out a field and its identifier.
  413. */
  414. void NetField(field, value)
  415. char *value, field;
  416.   {
  417.   fprintf(outfile, "%c%s", field, value);
  418.   putc(0, outfile);
  419.  
  420.   }
  421. /*
  422. * MoutCC()
  423. *
  424. * This handles the CC field of a message.
  425. */
  426. void MoutCC(dd)
  427. char *dd;
  428.   {
  429.   NetField('W', dd);
  430.  
  431.   }
  432. /*
  433. * MoutForeign()
  434. *
  435. * This handles the Foreign fields of a message.
  436. */
  437. void MoutForeign(dd)
  438. char *dd;
  439.   {
  440.   NetField(dd[0], dd + 1);
  441.  
  442.   }
  443. static int  RWorkBuf[7];
  444. /*
  445. * NowRouteMail()
  446. *
  447. * This function handles outgoing route mail.
  448. */
  449. void NowRouteMail()
  450.   {
  451.   int           rover;
  452.   label temp;
  453.   SYS_FILE      fn;
  454.   extern char *READ_ANY, OverRides;
  455.   if (!netBuf.nbflags.HasRouted)
  456.   return;
  457.   for (rover = 0; rover <= netBuf.nbHiRouteInd; rover++)
  458.     {
  459.     sPrintf(temp, "R%d.%d", thisNet, rover);
  460.     makeSysName(fn, temp, &cfg.netArea);
  461.     if ((netMisc = safeopen(fn, READ_ANY)) != NULL)
  462.       {
  463.       getMsgStr(getNetChar, temp, NAMESIZE);
  464.       getMsgStr(getNetChar, temp, NAMESIZE);
  465.       StartDecode(ReadRoutedDest);
  466.       RCount = SCount = 0;
  467.       while (getMessage(ReadRouted, TRUE, TRUE, TRUE))
  468.         {
  469.         strCpy(msgBuf.mbroom, "Mail");
  470.         NetFormat();
  471.  
  472.         }
  473.       fclose(netMisc);
  474.       unlink(fn);
  475.  
  476.       }
  477.  
  478.     }
  479.   netBuf.nbflags.HasRouted = FALSE;
  480.   netBuf.nbHiRouteInd        = 0;
  481.  
  482.   }
  483. /*
  484. * ReadRoutedDest()
  485. *
  486. * A work function to read encrypted data.
  487. */
  488. int ReadRoutedDest(int c)
  489.   {
  490.   RWorkBuf[RCount++] = c;
  491.   return TRUE;
  492.  
  493.   }
  494. /*
  495. * ReadRouted()
  496. *
  497. * This function will read a routed char for getMessage().
  498. */
  499. int ReadRouted()
  500.   {
  501.   int c;
  502.   if (RCount != SCount)
  503.   return RWorkBuf[SCount++];
  504.   RCount = SCount = 0;
  505.   while (SCount == RCount && (c = fgetc(netMisc)) != EOF)
  506.   Decode(c);
  507.   if (RCount != SCount)
  508.   return RWorkBuf[SCount++];
  509.   if (c == EOF) StopDecode();
  510.   if (RCount != SCount)
  511.   return RWorkBuf[SCount++];
  512.   return -1;
  513.  
  514.   }
  515. /*
  516. * getNetChar()
  517. *
  518. * This function gets a character from a network temporary file.
  519. */
  520. int getNetChar()
  521.   {
  522.   int c;
  523.   c = fgetc(netMisc);
  524.   if (c == EOF) return -1;
  525.   return c;
  526.  
  527.   }
  528. #define WeServe(x)      SearchList(&Serves, x)
  529. /*
  530. * LocalName()
  531. *
  532. * This takes a string of form <system> _ <domain> and attempts to discover if
  533. * this domain mapped system is actually a local.  This is used when we're
  534. * sending mail and are trying to find out if a Who Else override needs to be
  535. * generated.  Ugly kludge, but, hey, that's what programming's all about, eh?
  536. */
  537. char *LocalName(char *system)
  538.   {
  539.   char *domain, *System;
  540.   if ((domain = strchr(system, '_')) == NULL) return system;
  541.   domain += 2;  /* always preceded by a space -- or so we assume */
  542.   if (strCmpU(domain, cfg.codeBuf + cfg.nodeDomain) == SAMESTRING ||
  543.   WeServe(domain) != NULL)
  544.     {
  545.     System = strdup(system);
  546.     if ((domain = strchr(System, ' ')) == NULL)
  547.     return system;      /* should never happen, though */
  548.     *domain = NULL;
  549.     if (searchNameNet(System, &netTemp) != ERROR)
  550.       {
  551.       free(System);
  552.       return netTemp.netName;
  553.  
  554.       }
  555.     free(System);
  556.  
  557.     }
  558.   return system;
  559.  
  560.   }
  561. /*
  562. * SepNameSystem()
  563. *
  564. * This will parse an Other Recipient spec.
  565. */
  566. char SepNameSystem(char *string, char *person, char *system, NetBuffer *buf)
  567.   {
  568.   char  *c;
  569.   label domain;
  570.   char dup, work[150];          /* should be sufficient */
  571.   int   slot;
  572.   strCpy(work, string);
  573.   if ((c = strchr(work, '@')) == NULL)
  574.     {
  575.     if (strLen(work) >= NAMESIZE) return BAD_FORMAT;
  576.     strCpy(person, string);
  577.     return NOT_SYSTEM;
  578.  
  579.     }
  580.   *c++ = 0;
  581.   NormStr(work);
  582.   NormStr(c);
  583.   if (strLen(c) >= NAMESIZE * 2 || strLen(work) >= NAMESIZE)
  584.   return BAD_FORMAT;
  585.   strCpy(system, c);
  586.   strCpy(person, work);
  587.   if (buf == NULL) return IS_SYSTEM;    /* very minor cheat - see CTDL.C */
  588.   if ((slot = searchNameNet(c, buf)) != ERROR)
  589.     {
  590.     /* try secondary lists */
  591.     strCpy(system, buf->netName);       /* get "real" name */
  592.     if (buf->nbflags.local)
  593.       {
  594.       return IS_SYSTEM;
  595.  
  596.       }
  597.  
  598.     }
  599.   if (SystemInSecondary(c, domain, &dup))
  600.     {
  601.     if (dup)
  602.       {
  603.       /* oops */
  604.       return (char) ( (slot == ERROR) ? NO_SYSTEM : IS_SYSTEM );
  605.  
  606.       }
  607.     if (strCmpU(domain, cfg.nodeDomain + cfg.codeBuf) == SAMESTRING &&
  608.     (strCmpU(c, cfg.nodeName + cfg.codeBuf) == SAMESTRING ||
  609.     strCmpU(c, UseNetAlias(cfg.nodeName+cfg.codeBuf, TRUE))
  610.     == SAMESTRING))
  611.       {
  612.       printf("Hey, that's this system!\n ");
  613.       return (char)SYSTEM_IS_US;
  614.  
  615.       }
  616.     sPrintf(system, "%s _ %s", c, domain);
  617.     return (char)IS_SYSTEM;
  618.  
  619.     }
  620.   return (char) (slot == ERROR) ? NO_SYSTEM : IS_SYSTEM;
  621.  
  622.   }
  623. static label SearchResult;
  624. static char  *SearchTarget, GetAlias;
  625. /*
  626. * UseNetAlias()
  627. *
  628. * This will find a usenet alias or the converse.
  629. */
  630. char *UseNetAlias(char *Name, char FindAlias)
  631.   {
  632.   void *EatTrans();
  633.   SListBase Dummy =
  634.     {
  635.     NULL, NULL, NULL, NULL, EatTrans
  636.  
  637.     };
  638.   SYS_FILE fn;
  639.   char *c, *WorkName;
  640.   WorkName = strdup(Name);      /* use a work buffer */
  641.   SearchResult[0] = 0;
  642.   SearchTarget = WorkName;
  643.   if (!FindAlias) while ((c = strchr(WorkName, ' ')) != NULL) *c = '_';
  644.   makeSysName(fn, "aliases.sys", &cfg.roomArea);
  645.   GetAlias = FindAlias;
  646.   MakeList(&Dummy, fn, NULL);   /* CHEAT!  WHEEEEEE! */
  647.   free(WorkName);
  648.   if (strLen(SearchResult) == 0) return Name;
  649.   if (FindAlias) while ((c = strchr(SearchResult, '_')) != NULL) *c = ' ';
  650.   return SearchResult;
  651.  
  652.   }
  653. /*
  654. * EatTrans()
  655. *
  656. * This will eat a line of input for alias processing.
  657. */
  658. void *EatTrans(char *line)
  659.   {
  660.   char *c;
  661.   if ((c = strchr(line, ' ')) != NULL)
  662.     {
  663.     *c = 0;
  664.     if (GetAlias)
  665.       {
  666.       /* check second field */
  667.       if (strCmpU(c + 1, SearchTarget) == SAMESTRING)
  668.         {
  669.         strCpy(SearchResult, line);
  670.  
  671.         }
  672.  
  673.       }
  674.     else
  675.       {
  676.       /* check first field */
  677.       if (strCmpU(line, SearchTarget) == SAMESTRING)
  678.         {
  679.         strCpy(SearchResult, c + 1);
  680.  
  681.         }
  682.  
  683.       }
  684.  
  685.     }
  686.   return NULL;
  687.  
  688.   }
  689. /*
  690. * SearchSecondary()
  691. *
  692. * This searches a secondary (domain) list for a system.
  693. */
  694. static char SearchSecondary(char *secondary,char *Name,char *Domain,char *isdup)
  695.   {
  696.   FILE *fd;
  697.   int  bucket;
  698.   char found, *tab, *c, *tab2;
  699.   char line[90];
  700.   JumpInfo JumpTable[BUCKETCOUNT];
  701.   if ((fd = fopen(secondary, READ_ANY)) == NULL)
  702.   return FALSE;
  703.   fread(line, VERS_SIZE + 1, 1, fd);
  704.   fread(JumpTable, sizeof JumpTable, 1, fd);
  705.   #ifdef IS_MOTOROLA
  706.   for (bucket = 0; bucket < BUCKETCOUNT; bucket++)
  707.   Intel32ToMotorola(&JumpTable[bucket].offset);
  708.   #endif
  709.   bucket = (isdigit(Name[0])) ? Name[0] - '0' :
  710.   toUpper(Name[0]) - 'A' + 10;
  711.   fseek(fd, JumpTable[bucket].offset, 0);
  712.   found = FALSE;
  713.   do
  714.     {
  715.     *isdup = FALSE;
  716.     if (fgets(line, sizeof line, fd) == NULL) break;
  717.     if ((tab2 = strchr(line, '\n')) != NULL)
  718.     *tab2 = 0;
  719.     if (strlen(line) == 0)
  720.       {
  721.       break;
  722.  
  723.       }
  724.     if (line[0] <= ' ')
  725.       {
  726.       switch (line[0])
  727.         {
  728.         case DUP:
  729.         *isdup = TRUE;
  730.         break;
  731.         default: printf("Ooop!");
  732.         break;
  733.  
  734.         }
  735.       c = line + 1;
  736.  
  737.       }
  738.     else c = line;
  739.     tab = strchr(c, '\t');
  740.     *tab++ = 0;
  741.     if (strCmpU(c, Name) == 0)
  742.     found = TRUE;
  743.     if (strCmpU(c, Name) > 0) break;
  744.  
  745.     }
  746.   while (!found);
  747.   if (found)
  748.     {
  749.     if ((tab2 = strchr(tab, '\t')) != NULL)
  750.     *tab2++ = 0;
  751.     strCpy(Domain, tab);
  752.     if (tab2 != NULL)    /* alias?  Copy it into search string */
  753.     strCpy(Name, tab2);
  754.  
  755.     }
  756.   fclose(fd);
  757.   return found;
  758.  
  759.   }
  760. /*
  761. * SystemInSecondary()
  762. *
  763. * This will look for a system in secondary lists.
  764. */
  765. char SystemInSecondary(char *Name, char *Domain, char *dup)
  766.   {
  767.   int rover;
  768.   char *sep;
  769.   SYS_FILE secondary;
  770.   label name;
  771.   char WorkName[(NAMESIZE * 2) + 1];
  772.   char SearchSecondary(char *secondary,char *Name,char *Domain,char *isdup);
  773.   strCpy(WorkName, Name);
  774.   /* is the domain specified already?  if so, parse it */
  775.   if ((sep = strchr(WorkName, '_')) != NULL ||
  776.   (sep = strchr(WorkName, '.')) != NULL)
  777.     {
  778.     *sep++ = 0;
  779.     NormStr(WorkName);
  780.     NormStr(sep);
  781.     if (strchr(sep, '_') != NULL ||
  782.     strchr(sep, '.') != NULL)
  783.     return FALSE;       /* no subdomains */
  784.     strCpy(Name, WorkName);
  785.     strCpy(Domain, sep);
  786.     *dup = FALSE;               /* by definition */
  787.     return TRUE;
  788.  
  789.     }
  790.   Domain[0] = 0;
  791.   for (rover = 0; rover < 100; rover++)
  792.     {
  793.     sPrintf(name, "nodes%d.fst", rover);
  794.     makeSysName(secondary, name, &cfg.netArea);
  795.     if (access(secondary, 0) != 0) break;
  796.     if (SearchSecondary(secondary, Name, Domain, dup)) break;
  797.  
  798.     }
  799.   strCpy(WorkName, Name);
  800.   /* make sure we found something and it's not us */
  801.   return (Domain[0] != 0 &&
  802.   strCmpU(Name, cfg.codeBuf + cfg.nodeName) != SAMESTRING &&
  803.   strCmpU(UseNetAlias(WorkName,FALSE), cfg.codeBuf + cfg.nodeName)
  804.   != SAMESTRING);
  805.  
  806.   }
  807. extern VirtualRoom *VRoomTab;
  808. extern VirtNet     *VirtNetList;
  809. extern char VirtualInUse;
  810. extern int  VirtSize, VNetSize;
  811. /*
  812. * MODoVirtuals()
  813. *
  814. * This sends rooms to another system, if needed.
  815. */
  816. void MODoVirtuals()
  817.   {
  818.   int rover, which, x;
  819.   if (!VirtualInUse) return ;
  820.   for (rover = 0; rover < VIRT_LIMIT; rover++)
  821.     {
  822.     x = VirtNetList[thisNet].VirtList[rover].WhichVirt;
  823.     if (x >= VirtSize || x < 0 || !VRoomInuse(x))
  824.     VirtNetList[thisNet].VirtList[rover].WhichVirt = -1;
  825.     if (VirtNetList[thisNet].VirtList[rover].WhichVirt != -1)
  826.       {
  827.       SendVirtual(rover, NULL, NULL, NULL);
  828.  
  829.       }
  830.  
  831.     }
  832.  
  833.   }
  834. /*
  835. * SendVirtual()
  836. *
  837. * This manages sending a room to another system.
  838. */
  839. int SendVirtual(int VirtIndex, char *d1, char *d2, char *d3)
  840.   {
  841.   int   VirtNo, count;
  842.   MSG_NUMBER StartMsg;
  843.   VirtNo = VirtNetList[thisNet].VirtList[VirtIndex].WhichVirt;
  844.   /* Send all the new LD messages received */
  845.   StartMsg = VirtNetList[thisNet].VirtList[VirtIndex].LDSent;
  846.   count = ThrowAll(VirtNo, LD_DIR, StartMsg, VRoomTab[VirtNo].vrHiLD,
  847.   VRoomTab[VirtNo].vrName);
  848.   VirtNetList[thisNet].VirtList[VirtIndex].LDSent =
  849.   VRoomTab[VirtNo].vrHiLD;
  850.   if (VirtNetList[thisNet].VirtList[VirtIndex].mode != PEON)
  851.     {
  852.     StartMsg = VirtNetList[thisNet].VirtList[VirtIndex].LocSent;
  853.     count += ThrowAll(VirtNo, LOCAL_DIR, StartMsg,
  854.     VRoomTab[VirtNo].vrHiLocal, VRoomTab[VirtNo].vrName);
  855.     VirtNetList[thisNet].VirtList[VirtIndex].LocSent =
  856.     VRoomTab[VirtNo].vrHiLocal;
  857.  
  858.     }
  859.   VRoomTab[VirtNo].vrChanged |= SENT_DATA;
  860.   return count;
  861.  
  862.   }
  863. /*
  864. * ThrowAll()
  865. *
  866. * This sends a virtual room to another system.
  867. */
  868. static int ThrowAll(int which, char *distance, MSG_NUMBER start, MSG_NUMBER end,
  869. char *room)
  870.   {
  871.   MSG_NUMBER  rover;
  872.   int           count=0;
  873.   char  fn[100];
  874.   extern char *READ_ANY;
  875.   extern PROTO_TABLE Table[];
  876.   extern int    TransProtocol;
  877.   for (rover = start + 1; rover <= end; rover++)
  878.     {
  879.     CreateVAName(fn, which, distance, rover);
  880.     if ((netMisc = safeopen(fn, READ_ANY)) != NULL)
  881.       {
  882.       while (getMessage(getNetChar, TRUE, TRUE, TRUE))
  883.         {
  884.         count++;
  885.         strCpy(msgBuf.mbroom, room);
  886.         NetFormat();
  887.  
  888.         }
  889.       fclose(netMisc);
  890.  
  891.       }
  892.  
  893.     }
  894.   return count;
  895.  
  896.   }
  897. void Intel32ToMotorola(UNS_32 *val)
  898.   {
  899.   unsigned long temp;
  900.   temp = *val;
  901.   *val = ((ULONG)(temp & 0xff) << 24) + ((ULONG)(temp & 0xff00) << 8) +
  902.   ((ULONG)(temp & 0xff0000) >> 8) + ((ULONG)(temp &0xff000000) >> 24);
  903.  
  904.   }
  905.